package com.mianyang.zhangsan.plugin.export;

import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.Map;

/**
 * @author jiangjr
 * @date 2022-10-13
 */
@Slf4j
public class WordTemplate extends AbstractTemplate{
    /**
     * report对象
     */
    private final IXDocReport report;
    /**
     * 上下文变量
     */
    private final IContext context;

    public WordTemplate(InputStream in) {
        try {
            report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
            context = report.createContext();
        } catch (XDocReportException | IOException e) {
            log.error("word文档模板初始化异常");
            throw new RuntimeException("word文档模板初始化异常");
        }
    }

    @Override
    public void fill() {
        Map<String, Object> variable = this.getVariable();
        try {
            // 创建指定元数据
            FieldsMetadata fm = report.createFieldsMetadata();
            // 替换变量
            for (Map.Entry<String, Object> entry : variable.entrySet()) {
                context.put(entry.getKey(), entry.getValue());
                if (checkTable(entry.getKey())) {
                    // word模板种表格数对应的集合类型
                    fm.load(entry.getKey(), ITable.class, true);
                }
            }
        } catch (XDocReportException e) {
            log.error("word文档模板填充数据时异常");
            throw new RuntimeException("word文档模板填充数据时异常");
        }
    }

    @Override
    public OutputStream generator() {
        OutputStream out = new ByteArrayOutputStream();
        try {
            report.process(context, out);
        } catch (XDocReportException | IOException e) {
            log.error("word文档模板生成报告时异常-{}", e.getMessage());
            throw new RuntimeException("word文档模板生成报告时异常");
        }
        return out;
    }

    private boolean checkTable(String key) {
        return "table".equals(key) || "list".equals(key) || "step".equals(key);
    }
}
